--- 战斗主类
---
--- @class ReportManager
ReportManager = ClientFight.CreateClass("ReportManager")
local this = ReportManager

local isDebug = false
--[[
* 战报信息
* 攻击
]]
function this.attackToJsonString(fight, fighter, target, skill, speed)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.ATTACK;
    map["3"] = 0;

    local childMap = {};

    childMap["1"] = fighter.fighterId;
    childMap["2"] = target.fighterId;
    childMap["3"] = skill.skill.skillId;
    childMap["4"] = speed;
    local originalTargetPlacePoint = skill.originalTargetPlacePosition;
    if (originalTargetPlacePoint == nil) then
        originalTargetPlacePoint = Global.FIGHT_CENTER_POSITION;
    end
    childMap["7"] = originalTargetPlacePoint;
    childMap["10"] = skill.skillUniqueId;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[攻击]frame:%d,fighter:%d,target:%d,skill:%d,speed:%d,skillUniqueId:%d",
                fight.frame, fighter.fighterId, target.fighterId, skill.skill.skillId, speed, skill.skillUniqueId))
    end
    return map;
end

--[[
* 战报信息
* 技能触发技能
]]
function this.triggerSkillToJsonString(fight, fighter, target,
                                       parentSkillId, skillId, speed)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.TRIGGER_SKILL;
    map["3"] = 0;

    local childMap = {};

    childMap["1"] = fighter.fighterId;
    childMap["2"] = target.fighterId;
    childMap["3"] = parentSkillId;
    childMap["4"] = skillId;
    childMap["5"] = speed;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[技能触发技能]frame:%d,fighter:%d,target:%d,parentSkill:%d,skillId:%d,speed:%d",
                fight.frame, fighter.fighterId, target.fighterId, parentSkillId, skillId, speed))
    end
    return map;
end

--[[
* 战报信息
*
* @param fight
* @param fighter
* @param target
* @return
]]
function this.flyToJsonString(fight, fighter, target, fightUsingSkill)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.FLY;
    map["3"] = 0;

    local childMap = {};

    childMap["1"] = fighter.fighterId;
    childMap["2"] = target.fighterId;
    childMap["3"] = fightUsingSkill.skill.skillId;
    map["4"] = childMap;
    local originalTargetPlacePoint = fightUsingSkill.originalTargetPlacePosition;
    if (originalTargetPlacePoint == nil) then
        originalTargetPlacePoint = Global.FIGHT_CENTER_POSITION;
    end
    childMap["4"] = originalTargetPlacePoint;
    childMap["5"] = fightUsingSkill.fighter.fighterId;--真实的伤害来源
    childMap["10"] = fightUsingSkill.skillUniqueId;
    if (fightUsingSkill.startPosition ~= nil) then
        childMap["11"] = fightUsingSkill.startPosition;
    end
    if isDebug then
        logError(string.format("[飞行]frame:%d,fighter:%d,target:%d,skill:%d,skillFighter:%d,skillUniqueId:%d",
                fight.frame, fighter.fighterId, target.fighterId, fightUsingSkill.skill.skillId, fightUsingSkill.fighter.fighterId,
                fightUsingSkill.skillUniqueId))
    end
    return map;
end

--[[
* 锁定技能释放的 目标 坐标
*
* @param center 技能中心点
]]
function this.lockSkillReleasPosition(fight, fighter, target, center, fightUsingSkill)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.LOCK_SKILL_POSITION;
    map["3"] = 0;

    local childMap = {};

    childMap["1"] = fighter.fighterId;
    childMap["2"] = target.fighterId;
    childMap["3"] = fightUsingSkill.skill.skillId;
    --Vector2 originalTargetPlacePoint = fightUsingSkill.getFirstEffectPlacePosition();
    --if (originalTargetPlacePoint == nil){
    --    originalTargetPlacePoint = Global.FIGHT_CENTER_POSITION;
    --}
    childMap["4"] = Vector2.New(center.x, center.y);
    childMap["10"] = fightUsingSkill.skillUniqueId;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[锁定技能释放(坐标)]frame:%d,fighter:%d,target:%d,skill:%d,skillUniqueId:%d",
                fight.frame, fighter.fighterId, target.fighterId, fightUsingSkill.skill.skillId,
                fightUsingSkill.skillUniqueId))
    end
    return map;
end

--[[
* 战报信息
*
* @param fight
* @param fighter
* @param target
* @param skillId
* @return
]]
function this.hitToJsonString(fight, fighter, target, skillId,
                              damageState, skill)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.HIT;
    map["3"] = 0;

    local childMap = {};
    --        if (skill.getFlyBegin() ~= nil) {
    --            fighter = skill.getFlyBegin();
    --        }
    childMap["1"] = fighter.fighterId;
    childMap["2"] = target.fighterId;
    childMap["3"] = skillId;
    childMap["4"] = damageState;
    childMap["10"] = skill.skillUniqueId;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[受击]frame:%d,fighter:%d,target:%d,skill:%d,damageState:%d,skillUniqueId:%d",
                fight.frame, fighter.fighterId, target.fighterId, skillId, damageState, skill.skillUniqueId))

    end
    return map;
end

--[[
* 战报信息
*
* @param fight
* @param fighter
* @param target
* @param skillId
* @return
]]
function this.damageToJsonString(fight, fighter, target, skillId,
                                 skillFrame, damageState, damage, skillUUID, skill)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.DAMAGE;
    map["3"] = 0;

    local childMap = {};

    --        if (skill ~= nil && skill.getFlyBegin() ~= nil) {
    --            fighter = skill.getFlyBegin();
    --        }
    childMap["1"] = fighter.fighterId;
    childMap["2"] = target.fighterId;
    childMap["3"] = damage;
    childMap["4"] = damageState;
    childMap["5"] = skillId;
    childMap["6"] = skillFrame;
    childMap["10"] = skillUUID;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[伤害]frame:%d,fighter:%d,target:%d,damage:%d,damageState:%d,skill:%d,skillFrame:%d,uuid:%d",
                fight.frame, fighter.fighterId, target.fighterId, damage, damageState, skillId, skillFrame, skillUUID))
    end
    return map;
end

--[[
* 战报信息
*
* @param fight
* @param fighter
* @param target
* @param skillId
* @return
]]
function this.shieldToJsonString(fight, fighter, target, skillId,
                                 skillFrame, change)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.DAMAGE;
    map["3"] = 0;

    local childMap = {};

    childMap["1"] = fighter.fighterId;
    childMap["2"] = target.fighterId;
    childMap["3"] = change;
    childMap["4"] = DamageResultTypeEnum.SHIELD;
    childMap["5"] = skillId;
    childMap["6"] = skillFrame;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[伤害]frame:%d,fighter:%d,target:%d,change:%d,护盾,skillId:%d,skillFrame:%d",
                fight.frame, fighter.fighterId, target.fighterId, change, skillId, skillFrame))
    end
    return map;
end

--[[
* 战报信息
*
* @param fight
* @param fighter
* @param target
* @param skillId
* @return
]]
function this.energyToJsonString(fight, fighter, target, skillId,
                                 skillFrame, energy)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.DAMAGE;
    if (skillId == 0) then
        map["3"] = 1;
    else
        map["3"] = 0;
    end

    local childMap = {};

    childMap["1"] = fighter.fighterId;
    childMap["2"] = target.fighterId;
    childMap["3"] = energy;
    childMap["4"] = DamageResultTypeEnum.ENERGY;
    childMap["5"] = skillId;
    childMap["6"] = skillFrame;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[伤害]frame:%d,fighter:%d,target:%d,energy:%d,能量,skillId:%d,skillFrame:%d",
                fight.frame, fighter.fighterId, target.fighterId, energy, skillId, skillFrame))
    end
    return map;
end

--[[
* 战报信息
*
* @param fight
* @param fighter
* @param target
* @param skillId
* @return
]]
function this.healToJsonString(fight, fighter, target, skillId,
                               skillFrame, damage, skillUUID)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.DAMAGE;
    map["3"] = 0;

    local childMap = {};

    childMap["1"] = fighter.fighterId;
    childMap["2"] = target.fighterId;
    childMap["3"] = damage;
    childMap["4"] = DamageResultTypeEnum.HEAL;
    childMap["5"] = skillId;
    childMap["6"] = skillFrame;
    childMap["10"] = skillUUID;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[伤害]frame:%d,fighter:%d,target:%d,damage:%d,治疗,skillId:%d,skillFrame:%d",
                fight.frame, fighter.fighterId, target.fighterId, damage, skillId, skillFrame))
    end
    return map;
end

--[[
* 战报信息
*
* @param fight
* @param fighter
* @param target
* @return
]]
function this.realHealToJsonString(fight, fighter, target,
                                   damage)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.DAMAGE;
    map["3"] = 1;

    local childMap = {};

    childMap["1"] = fighter.fighterId;
    childMap["2"] = target.fighterId;
    childMap["3"] = damage;
    childMap["4"] = DamageResultTypeEnum.HEAL;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[伤害]frame:%d,fighter:%d,target:%d,damage:%d,治疗",
                fight.frame, fighter.fighterId, target.fighterId, damage))
    end
    return map;
end

--[[
* 战报信息
*
* @param fight
* @param fighter
* @param target
* @return
]]
function this.realDamageToJsonString(fight, fighter, target,
                                     damageState, damage)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.DAMAGE;
    map["3"] = 1;

    local childMap = {};
    childMap["1"] = fighter.fighterId;
    childMap["2"] = target.fighterId;
    childMap["3"] = damage;
    childMap["4"] = damageState;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[伤害]frame:%d,fighter:%d,target:%d,damage:%d,damageState:%d",
                fight.frame, fighter.fighterId, target.fighterId, damage, damageState))
    end
    return map;
end

--[[
* 战报信息
*
* @param fight
* @param fighter
* @return
]]
function this.moveToJsonString(fight, fighter)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.MOVE;

    local childMap = {};

    map["4"] = childMap;
    childMap["1"] = fighter.fighterId;

    return map;
end

--[[
* 战报信息 移动到目的地
*
* @param fight
* @param fighter
* @param action
* @return
]]
function this.setMoveEndToJsonString(fight, fighter, action)
    if (action == nil) then
        return ;
    end
    action["1"] = fight.frame;
    action["2"] = FightActionType.MOVE;
    local childMap = action["4"];
    childMap["2"] = fight.frame;
    childMap["3"] = Vector2.New(fighter.position.x, fighter.position.y);
end

--[[
* 战报信息
*
* @param fight
* @param fighter
* @return
]]
function this.setMoveAttackEndToJsonString(fight, fighter, action)
    if (action == nil) then
        return ;
    end
    local childMap = action["4"];
    childMap["4"] = fight.frame;
    childMap["5"] = Vector2.New(fighter.position.x, fighter.position.y);
end

function this.isMoveAttackOf(skill, action)
    if (action == nil) then
        return false;
    end
    local childMap = action["4"];

    local skillId = childMap["3"] or 0;
    if (skillId ~= skill.skill.skillBean.f_skillId) then
        return false;
    end

    local skillUUID = childMap["10"] or 0;
    return skillUUID == skill.skillUniqueId;
end

--[[
* 战报信息 设置坐标
* 直接设置位置
* @param type {@link MoveType}
* @param orientation 目标朝向 没有的话客户都安维持现有朝向
]]
function this.changePointToJsonString(fight, fighter, type,
                                      orientation)
    return changePointOnBeFly(fight, fighter, type, orientation, 0, 0);
end

--[[
* 被击飞
* @param finishFrame 结束帧
* @param high 击飞时的高度
* @param type {@link MoveType}
* @param orientation 朝向哪个目标
]]
function this.changePointOnBeFly(fight, fighter, type,
                                 orientation, finishFrame, high)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.CHANGE_POINT;

    local childMap = {};

    childMap["1"] = fighter.fighterId;
    childMap["2"] = type;
    childMap["3"] = Vector2.New(fighter.position.x, fighter.position.y);
    if (orientation ~= nil) then
        childMap["4"] = orientation.fighterId;
    else
        childMap["4"] = 0;
    end
    childMap["5"] = finishFrame;
    childMap["6"] = high;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[直接设置位置]frame:%d,fighter:%d,pos:(%02f,%02f),orientation:%d,finishFrame:%d,high:%d",
                fight.frame, fighter.fighterId, fighter.position.x, fighter.position.y, childMap["4"], finishFrame, high))
    end
    return map;
end

--[[
* 战报信息
*
* @param type 0:增加 1:移除 2:变更层数 3:变更池
* @return
]]
---@param buff FighterBuff
function this.buffToJsonString(fight, buff, type)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.BUFF;
    map["3"] = type;

    local childMap = {};

    childMap["1"] = buff.source.fighterId;
    childMap["2"] = buff.target.fighterId;
    childMap["3"] = buff.modelId;
    childMap["4"] = buff.id; -- 唯一id
    childMap["5"] = buff.overlay; -- buff层数
    childMap["6"] = buff.pool.type; -- 池类型（1是血池）
    if buff.pool.type ~= BuffPoolEnum.NONE then
        childMap["7"] = buff.pool.max; -- 池最大值
        childMap["8"] = buff.pool.current; -- 池当前值
    end
    --childMap["9"] = buff.skill.skill.skillBean.f_skillId;
    map["4"] = childMap;
    if isDebug then
        --logError(string.format("[BUFF]frame:%d,fighter:%d,target:%d,BuffModelId:%d,buffId:%d,overlay:%d,skillModelId:%s",
        --        fight.frame, buff.source.fighterId, buff.target.fighterId, buff.modelId, buff.id, buff.overlay, tostring(buff.skill.skill.skillBean.f_skillId)))

    end
    return map;
end

--[[
* 战报信息
*
* @param type  0:战斗单位 1:基于队伍的一个虚的fighter，用于释放支援技或其他全局技能
* @param fight
* @return
]]
function this.fighterToJsonString(fight, fighter, type)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.INIT;
    map["3"] = type;

    local childMap = {};

    childMap["1"] = fighter.fighterId;
    childMap["2"] = fighter.modelId;
    childMap["3"] = FighterAttributeManager.getFightAttr(fighter, FighterAttributeEnum.HP);
    childMap["4"] = fighter.hp;
    childMap["5"] = fighter.maxEnergy;
    childMap["6"] = fighter.energy;
    childMap["7"] = fighter.teamIndex - 1;

    local positionMap = {};
    childMap["8"] = positionMap;
    positionMap["1"] = fighter.position.x;
    positionMap["2"] = fighter.position.y;

    childMap["9"] = fighter.weaponLevel;
    childMap["10"] = fighter.skin;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[INIT]frame:%d,fighter:%d,model:%d,hp:%d,energy:%d,teamIndex:%d,position:(%02f,%02f)",
                fight.frame, fighter.fighterId, fighter.modelId, fighter.hp, fighter.energy, fighter.teamIndex, fighter.position.x, fighter.position.y))
    end
    return map;
end

--[[
* 战报信息：召唤物上场
*
]]
function this.summonToJsonString(fight, fighter,isInit)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.INIT_SUMMON;
    map["3"] = isInit and 1 or 0;

    local childMap = {};

    childMap["1"] = fighter.fighterId;
    childMap["2"] = fighter.modelId;
    childMap["3"] = FighterAttributeManager.getFightAttr(fighter, FighterAttributeEnum.HP);
    childMap["4"] = fighter.hp;
    childMap["5"] = fighter.maxEnergy;
    childMap["6"] = fighter.energy;
    childMap["7"] = fighter.teamIndex - 1;

    local positionMap = {};
    childMap["8"] = positionMap;
    positionMap["1"] = fighter.position.x;
    positionMap["2"] = fighter.position.y;

    childMap["9"] = fighter.weaponLevel;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[初始化召唤物]frame:%d,fighter:%d,model:%d,hp:%d,energy:%d,teamIndex:%d,position:(%02f,%02f)",
                fight.frame, fighter.fighterId, fighter.modelId, fighter.hp, fighter.energy, fighter.teamIndex, fighter.position.x, fighter.position.y))

    end
    return map;
end

--[[
* 战报信息：替补上场
*
]]
function this.enterSceneToJsonString(fight, fighter)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.ENTER_SCENE;
    map["3"] = 0;

    local childMap = {};

    childMap["1"] = fighter.fighterId;
    childMap["2"] = fighter.modelId;
    childMap["3"] = FighterAttributeManager.getFightAttr(fighter, FighterAttributeEnum.HP);
    childMap["4"] = fighter.hp;
    childMap["5"] = fighter.maxEnergy;
    childMap["6"] = fighter.energy;
    childMap["7"] = fighter.teamIndex - 1;

    local positionMap = {};
    childMap["8"] = positionMap;
    positionMap["1"] = fighter.position.x;
    positionMap["2"] = fighter.position.y;

    childMap["9"] = fighter.weaponLevel;
    childMap["10"] = fighter.skin;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[替补入场]frame:%d,fighter:%d,model:%d,hp:%d,energy:%d,teamIndex:%d,position:(%02f,%02f)",
                fight.frame, fighter.fighterId, fighter.modelId, fighter.hp, fighter.energy, fighter.teamIndex, fighter.position.x, fighter.position.y))
    end
    return map;
end


function this.intSceneToJsonString(fight, fighter)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.INIT_ALTERNATE;
    map["3"] = 0;

    local childMap = {};

    childMap["1"] = fighter.fighterId;
    childMap["2"] = fighter.modelId;
    childMap["3"] = FighterAttributeManager.getFightAttr(fighter, FighterAttributeEnum.HP);
    childMap["4"] = fighter.hp;
    childMap["5"] = fighter.maxEnergy;
    childMap["6"] = fighter.energy;
    childMap["7"] = fighter.teamIndex - 1;

    local positionMap = {};
    childMap["8"] = positionMap;
    positionMap["1"] = fighter.position.x;
    positionMap["2"] = fighter.position.y;

    childMap["9"] = fighter.weaponLevel;
    childMap["10"] = fighter.skin;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[替补入场]frame:%d,fighter:%d,model:%d,hp:%d,energy:%d,teamIndex:%d,position:(%02f,%02f)",
                fight.frame, fighter.fighterId, fighter.modelId, fighter.hp, fighter.energy, fighter.teamIndex, fighter.position.x, fighter.position.y))
    end
    return map;
end

--[[
* 战报信息
*
* @param fight
* @return
]]
function this.dieToJsonString(fight, fighter, dieType, killer)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.DIE;
    map["3"] = dieType;

    local childMap = {};
    map["4"] = childMap;

    childMap["1"] = fighter.fighterId;
    childMap["2"] = killer == nil and 0 or killer.fighterId;
    if (fighter == killer or killer == nil) then
        if (fighter.lastDamageMe ~= 0) then
            childMap["2"] = fighter.lastDamageMe;
        end
    end
    if isDebug then
        logError(string.format("[死亡]frame:%d,fighter:%d,killer:%d",
                fight.frame, fighter.fighterId, childMap["2"]))
    end
    return map;
end

--[[
* 复活战报信息
*
* @param fight   战斗数据
* @param fighter 战士数据
* @return
]]
function this.reviveToJsonString(fight, fighter)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.REVIVE;
    map["3"] = 0;

    local childMap = {};
    map["4"] = childMap;

    childMap["1"] = fighter.fighterId;
    if isDebug then
        logError(string.format("[复活]frame:%d,fighter:%d",
                fight.frame, fighter.fighterId))
    end
    return map;
end

--[[
* 格挡战报信息
*
* @param fight   战斗数据
* @param fighter 战士数据
* @return
]]
function this.additionalStateToJsonString(fight, fighter, state)
    local map = {};
    map["1"] = fight.frame;
    map["2"] = FightActionType.ADDITIONAL_STATE;
    map["3"] = 0;

    local childMap = {};
    childMap["1"] = fighter.fighterId;
    childMap["2"] = state.id;
    map["4"] = childMap;
    if isDebug then
        logError(string.format("[额外状态]frame:%d,fighter:%d,state:%d",
                fight.frame, state.id))
    end
    return map;
end
